#include <iostream>

using namespace std;

struct A
{
	int _i = 0;
	int _val = 10;

	A(int i)
	{ 
		_i = i;
		cout << "A()" << endl;
	}

	virtual ~A() { cout << "~A()" << endl; }

	virtual int getVal() { return 0; }
	virtual void setVal(int i) {}
};

struct GetA : virtual public A
{
	int _j = 0;
	GetA(int j) : A(0) 
	{
		_j = j;
		cout << "GetA()" << endl; 
	}

	virtual ~GetA() { cout << "~GetA()" << endl; }

	int getVal() override { return _val; }
};

struct SetA : virtual public A
{
	SetA() : A(0) { cout << "SetA()" << endl; }
	virtual ~SetA() { cout << "~SetA()" << endl; }

	void setVal(int i) override { _val = i; }
};

struct B : public GetA, public SetA
{
	//B(int i) : A(i) { cout << "B()" << endl; }
	B(int i, int j) : GetA(j), A(i) { cout << "B()" << endl; }
	virtual ~B() { cout << "~B()" << endl; }
};

struct C : public GetA
{
	C(int j) : GetA(j), A(0) { cout << "C()" << endl; }
};

struct D : public C
{
	D(int i, int j) : C(j), A(i) { cout << "D()" << endl; }
};

int main()
{
	B b(20, 30);
	cout << "b.getVal()=" << b.getVal() << endl;
	b.setVal(20);
	cout << "b.getVal()=" << b.getVal() << endl;
	cout << "b._i=" << b._i << endl;
	cout << "b._j=" << b._j << endl;
	cout << endl;
	C c(40);
	cout << "c._i=" << c._i << endl;
	cout << "c._j=" << c._j << endl;
	cout << endl;
	D d(50, 60);
	cout << "d._i=" << d._i << endl;
	cout << "d._j=" << d._j << endl;
}